#ifndef TCP_SERVER_CONNECTIONPOOL_H
#define TCP_SERVER_CONNECTIONPOOL_H

#include "../base/thread/Mutex.h"
#include "../base/Timestamp.h"
#include "MySQLConnection.h"

#include <vector>
#include <unordered_map>
#include <deque>

class ConnectionPool {
public:

    /*  class DataBaseConnection{
      public:

          DataBaseConnection();

          DataBaseConnection(const Timestamp & expire, MySQLConnection * conn, int64_t index);

          ~DataBaseConnection();

          *//**
         * 返回对象维护的连接是否有效
         * @return
         *//*
        bool expire();

        bool query(const string & sql);

        MySQLConnection::fieldsVector select(const string & sql);

    private:

        friend ConnectionPool;

        void destroyConn();

        bool isValid_;
        Timestamp expire_;
        MySQLConnection * connection_;
        int64_t index_;
        // 维护连接,
    };*/

    typedef MySQLConnection *Connection;

    ConnectionPool(int numConnections,
                   string connectionName,
                   string database,
                   string username,
                   string password,
                   string host = "localhost",
                   int port = 3306);

    ConnectionPool(int numConnections,
                   const string &database,
                   const string &username,
                   const string &password,
                   const string &host = "localhost",
                   int port = 3306);

    ~ConnectionPool();

    /**
     * 获取数据库连接的指针
     * @return 返回一个数据库连接
     */
    Connection getConnection();

    void closeConnection(Connection *conn);

    void setMaxNumConnections(int maxNumConnections) {
        this->maxNumConnections_ = maxNumConnections;
    }

    int getCurNumConnections() const {
        return this->numConnections_;
    }

    int getMaxNumConnections() const {
        return this->maxNumConnections_;
    }

    void destroyConnPool();

private:
    // typedef MySQLConnection* ConnectionPtr;
    typedef std::deque<Connection> ConnectionDeque;
    typedef std::vector<Connection> ConnectionVector;
    //typedef std::unordered_map<ConnectionPtr, int> ConnectionVector;
    typedef std::unordered_set<Connection> ExpiredConnections;
    // FIXME: 后面有时间再研究连接封装

    /**
     * 创建一个数据库连接并添加到数据库队列中
     * 没有上锁, 需要连接池自己加锁调用
     */
    void addConnection(int index);

    /**
     * 从队列中获取一个连接, 并将连接存入活动队列中
     * 没有上锁, 需要连接池自己加锁调用
     * @return
     */
    Connection getConnFromQue();

    bool isDestroying_;

    int numConnections_;
    int maxNumConnections_;
    string name_;
    int64_t nextInd_;

    string database_;
    string username_;
    string password_;
    string host_;
    int port_;

    ConnectionDeque freeConnections_;
    ConnectionVector connections_;
    // 维护连接
    ExpiredConnections activeConnections_;
    MutexLock mutex_;
};


#endif //TCP_SERVER_CONNECTIONPOOL_H
